﻿using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class LchVolumneFogRenderer : ScriptableRendererFeature
{
    class CustomRenderPass : ScriptableRenderPass
    {

        private static readonly int _FogColor = Shader.PropertyToID("_FogColor");
        private static readonly int _HeightFogParam2 = Shader.PropertyToID("_HeightFogParam2");
        private static readonly int _FogDir = Shader.PropertyToID("_FogDir");

        private static readonly int TempTargetId = Shader.PropertyToID("_TempTargetColorTint");

        private Material material;

        //private RenderTargetHandle tempTexture;
        private LchVolumneFog settings;



        public CustomRenderPass(Material mat)
        {
            material = mat;
            if (material == null)
            {
                Shader shader = Shader.Find("Hidden/LchVolumneFog");
                if (shader != null) material = new Material(shader);
            }
        }

        public void Setup(LchVolumneFog settings)
        {

            this.settings = settings;

        }

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {


            CommandBuffer cmd = CommandBufferPool.Get("Custom Post Processing");


#if UNITY_2022_1_OR_NEWER
            // Unity 2022 及以后的版本
            var source = renderingData.cameraData.renderer.cameraColorTargetHandle;

#else
        // 旧版本的 Unity
        var source =    renderer.cameraColorTarget;
#endif



            material.SetVector(_HeightFogParam2, new Vector4(settings._NoiseScale1.value, settings._NoiseScale2.value, settings._Density.value, settings._Near.value));

            Color fogColor = settings._FogColor.value;
            fogColor.a = settings._FogMax.value;
            material.SetColor(_FogColor, fogColor);

            var d1 = settings.dir1.value;
            var d2 = settings.dir2.value;
            material.SetVector(_FogDir, new Vector4(d1.x, d1.y, d2.x, d2.y));

            if (settings.fogNoise.value != null)
            {
                material.SetTexture("_Noise3DTex", settings.fogNoise.value);
            }




            int dest = TempTargetId;

            cmd.GetTemporaryRT(dest, renderingData.cameraData.camera.scaledPixelWidth, renderingData.cameraData.camera.scaledPixelHeight, 0, FilterMode.Trilinear, RenderTextureFormat.Default);


            cmd.Blit(source, dest);
            cmd.Blit(dest, source, material, 0);



            cmd.ReleaseTemporaryRT(dest);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }

        public override void OnCameraCleanup(CommandBuffer cmd)
        {
            cmd.ReleaseTemporaryRT(TempTargetId);
        }
    }

    private CustomRenderPass pass;
    public Material material;

    public override void Create()
    {
        if (material == null)
        {
            Shader shader = Shader.Find("Hidden/LchVolumneFog");
            if (shader != null) material = new Material(shader);
        }

        pass = new CustomRenderPass(material)
        {
            renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing
        };
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        var stack = VolumeManager.instance.stack;
        var settings = stack.GetComponent<LchVolumneFog>();

        if (settings == null || !settings.active || !settings.IsActive()) return;

        pass.Setup(settings);
        renderer.EnqueuePass(pass);
    }
}
